﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System.Threading;
using BrainTechLLC.ThreadSafeObjects;
using System.Collections.Generic;
using System;
using System.Reflection;

namespace BrainTechLLC
{
    public class PluginDefinitionLoadedBase : BaseNotifyPropertyChanged
    {
    }

    public class PluginDefinitionLoaded<TPlugin> : PluginDefinitionLoadedBase 
        where TPlugin : class     
    {
        public event EventHandler<ObjectEventArgs<TPlugin>> HandlerSet;
        protected object _lockObject = new object();
        public List<AssemblyAndType> Handlers = new List<AssemblyAndType>();
        protected TPlugin _Handler;
        protected object _Window;
        public Action<PluginDefinitionLoaded<TPlugin>, TPlugin> PostLoadAction;

        public bool IsLoaded
        {
            get { return _Handler != null; }
        }

        public PluginDefinitionLoaded(object window)
        {
            _Window = window;
        }

        public object Window
        {
            get { return _Window; }
            set
            {
                if (_Window != value)
                {
                    _Window = value;
                    OnPropertyChanged("Window");
                }
            }
        }

        public TPlugin Handler
        {
            get
            {
                if (_Handler == null)
                {
                    if (Handlers.Count == 0)
                    {
                        throw new Exception(string.Format("No Handler of type {0} found!", typeof(TPlugin).Name));
                    }

                    lock (_lockObject)
                    {
                        if (_Handler == null)
                        {
                            var asmAndType = Handlers[0];
#if SILVERLIGHT
#else
                            Assembly a = Assembly.LoadFile(asmAndType.FileName);
                            Type type = a.GetType(asmAndType.TypeName);

                            TPlugin handler = type.GetConstructor(new Type[] { _Window.GetType(), typeof(PluginDefinitionLoaded<TPlugin>) }).Invoke(new object[] { _Window, this }) as TPlugin;

                            _Handler = handler;
                            OnPropertyChanged("IsLoaded");
                            OnPropertyChanged("Handler");
                            HandlerSet.RaiseEvent(this, _Handler);

                            Console.WriteLine(string.Format("{0} loaded.", type.FullName));
#endif
                        }
                    }
                }
                return _Handler;
            }
        }

    }
}
